#include "freertos/task.h"
#include "freertos/FreeRTOS.h"
#include "esp_log.h"

#include "i2c_bus.h"

#define  _I2C_SLAVE_ADDR         0x38
#define  TOUCH_I2C_PORT          I2C_NUM_0
#define  I2C_MASTER_SDA         12
#define  I2C_MASTER_SCL          14

#define  I2C_MASTER_FREQ_HZ      (40*10000)


// 主要用于写入指令和寄存器
esp_err_t i2c_write_reg_8bit(uint8_t reg_addr)
{
    i2c_cmd_handle_t i2c_cmd = i2c_cmd_link_create();
    i2c_master_start(i2c_cmd);
    i2c_master_write_byte(i2c_cmd, (_I2C_SLAVE_ADDR << 1) | I2C_MASTER_WRITE, true);
    i2c_master_write_byte(i2c_cmd, reg_addr, true);
    // i2c_master_write_byte(i2c_cmd, data, true);
    i2c_master_stop(i2c_cmd);
    esp_err_t ret = i2c_master_cmd_begin(TOUCH_I2C_PORT, i2c_cmd, 1000 / portTICK_PERIOD_MS);
    i2c_cmd_link_delete(i2c_cmd);
    return ret;
}

// 读取I2C中固定的8位数据
esp_err_t i2c_read_reg_8bit(uint8_t reg_addr, uint8_t* data)
{
    i2c_cmd_handle_t i2c_cmd = i2c_cmd_link_create();
    i2c_master_start(i2c_cmd);
    i2c_master_write_byte(i2c_cmd, (_I2C_SLAVE_ADDR << 1) | I2C_MASTER_WRITE, true);
    i2c_master_write_byte(i2c_cmd, reg_addr, true);
    i2c_master_start(i2c_cmd);
    i2c_master_write_byte(i2c_cmd, (_I2C_SLAVE_ADDR << 1) | I2C_MASTER_READ, true);
    i2c_master_read_byte(i2c_cmd, data, I2C_MASTER_LAST_NACK);
    i2c_master_stop(i2c_cmd);
    esp_err_t ret = i2c_master_cmd_begin(TOUCH_I2C_PORT, i2c_cmd, 1000 / portTICK_PERIOD_MS);
    i2c_cmd_link_delete(i2c_cmd);
    return ret;
}

// 读取I2C中不同长度的数据
esp_err_t i2c_read_reg_n(uint8_t reg_addr, uint8_t* buffer, size_t len)
{
    if (len == 0) {
        return ESP_OK;
    }

    i2c_cmd_handle_t i2c_cmd = i2c_cmd_link_create();
    i2c_master_start(i2c_cmd);
    i2c_master_write_byte(i2c_cmd, (_I2C_SLAVE_ADDR << 1) | I2C_MASTER_WRITE, true);
    i2c_master_write_byte(i2c_cmd, reg_addr, true);
    i2c_master_start(i2c_cmd);
    i2c_master_write_byte(i2c_cmd, (_I2C_SLAVE_ADDR << 1) | I2C_MASTER_READ, true);

    if (len > 1) {
        i2c_master_read(i2c_cmd, buffer, len - 1, I2C_MASTER_ACK);
    }

    i2c_master_read_byte(i2c_cmd, buffer + len - 1, I2C_MASTER_LAST_NACK);
    i2c_master_stop(i2c_cmd);
    esp_err_t ret = i2c_master_cmd_begin(TOUCH_I2C_PORT, i2c_cmd, 1000 / portTICK_PERIOD_MS);
    i2c_cmd_link_delete(i2c_cmd);

    return ret;
}

// 初始化I2C
esp_err_t i2c_init(i2c_config_t* i2c_config)
{
    i2c_config_t config;
    if(i2c_config == NULL){
        config .mode = I2C_MODE_MASTER;
        config.sda_io_num = I2C_MASTER_SDA;
        config.scl_io_num = I2C_MASTER_SCL;
        config .sda_pullup_en = GPIO_PULLUP_ENABLE;
        config .scl_pullup_en = GPIO_PULLUP_ENABLE;
        config .master.clk_speed = I2C_MASTER_FREQ_HZ;
    }else{
        config .mode = i2c_config->mode;
        config.sda_io_num = i2c_config->scl_io_num;
        config.scl_io_num = i2c_config->sda_io_num;
        config .sda_pullup_en = i2c_config->sda_pullup_en;
        config .scl_pullup_en = i2c_config->scl_pullup_en;
        config .master.clk_speed = i2c_config->clk_flags;
    }
    
	esp_err_t ret_err = i2c_param_config(TOUCH_I2C_PORT, &config);
    // 初始化I2C总线
	if(ret_err == ESP_OK){
		ret_err = i2c_driver_install(TOUCH_I2C_PORT, config.mode, 0, 0, 0);
		if(ret_err != ESP_OK){
			ESP_LOGI("i2c init failed");
		}
	}
   return ret_err;
}

